<?php
error_reporting(E_ALL | E_STRICT);

define('DS', DIRECTORY_SEPARATOR);
define('ROOT', (dirname(dirname(__FILE__))) . DS);

$mahees_framework_path = ROOT.'components'.DS.'emerald_framework'.DS;
require($mahees_framework_path.DS.'framework_initializer.php');


class Route {

	private static $table = array();

	static function insert_into_route_table($sTemplate, $aRoute = array()) {
		self::$table[$sTemplate] = $aRoute;
	}

	static function get_routes() {
		return self::$table;
	}
	
}

class Dispatch {

	private static $cai = array('controller' => false, 'action' => 'index', 'id' => NULL), $aGetRUrl = false;

	function Dispatch() {
		//self::$aGetRUrl = self::aClean_url($_GET['r']);
		//unset($_GET['r']);
	}

	static function  __callStatic($name, $arguments) {
		
	}
	
	static function dispatcher() {
		self::$aGetRUrl = self::aClean_url($_GET['r']);
		unset($_GET['r']);
		
		require(CONFIG . 'routes.php');

		foreach(Route::get_routes() as $sTemplate => $aRoute) {
			if (count(self::$aGetRUrl) > 0) {
				$aTemplate = self::aClean_url($sTemplate);
				if (!count($aTemplate)) { continue; }
				foreach($aTemplate as $key => $rule) {
					if ($rule[0] == ':') { //wildcard
						$ruleName = substr($rule, 1);
						if (isset(self::$aGetRUrl[$key])) {	self::$cai[$ruleName] = self::$aGetRUrl[$key]; unset($aRoute[$ruleName]); }
						elseif (!isset(self::$cai[$ruleName])) { self::$cai[$ruleName] = null; }
					}
					elseif ($rule != self::$aGetRUrl[$key]) { continue 2; }
				}
			}
			//must have matched template
			foreach($aRoute as $key => $val) { self::$cai[$key] = $aRoute[$key]; }
			foreach(self::$cai as $key => $val) { $_GET[$key] = $val; }
			self::execute_controller_action();
			break;
		}
	}


	//the way i see it now, connect sould just drop all the routes into the routes table
	static function connect($sTemplate, $aRoute = array()) {
		Route::insert_into_route_table($sTemplate, $aRoute);
	}

/*
	function connect($sTemplate, $aRoute = array()) {
		if (count(self::$aGetRUrl) > 0) {
			$aTemplate = self::aClean_url($sTemplate);
			if (!count($aTemplate)) { return false; }
			foreach($aTemplate as $key => $rule) {
				if ($rule[0] == ':') { //wildcard
					$ruleName = substr($rule, 1);
					if (isset(self::$aGetRUrl[$key])) {	self::$cai[$ruleName] = self::$aGetRUrl[$key]; unset($aRoute[$ruleName]); }
					elseif (!isset(self::$cai[$ruleName])) { self::$cai[$ruleName] = null; }
				}
				elseif ($rule != self::$aGetRUrl[$key]) { return false; }
			}
		}
		//must have matched template
		foreach($aRoute as $key => $val) { self::$cai[$key] = $aRoute[$key]; }
		foreach(self::$cai as $key => $val) { $_GET[$key] = $val; }
		print_r($_GET);
		self::execute_controller_action();
		
		die();
	}
*/


	static function execute_controller_action() {
		$controller = $_GET['controller'];
		$action = $_GET['action'];
		$controllerClassName = ucfirst($controller).'_controller';
		$controller_file = APPLICATION_PATH.'controllers'.DS.$controllerClassName.'.php';
		if (file_exists($controller_file)) {
			require($controller_file);
			if ($controller_instance = new $controllerClassName()) {
				if (method_exists($controller_instance, $action)) {
					if (!$controller_instance->$action()) { //basically of the function doesnt return anything i render somthing
						return $controller_instance->render();
					}
				}
				echo 'action DOESNT exist in specified class';
				return false;
			}
			echo 'no class found! or couldnt create instance of it!';
			return false;
		}
		echo 'controller file not found';
		return false;
	}


	private static function aClean_url($sUrl) {
		if ($sUrl === '') { return array(); }
		$aUrl = explode('/', $sUrl);
		if (end($aUrl) == '') {	array_pop($aUrl); }
		return $aUrl;
	}
/*
	static function link_to($params = array()){
		foreach(Route::get_routes() as $sTemplate => $aRoute) {
			$aTemplate = explode('/', $sTemplate);
			foreach($params as $k => $v) {
				if (array_key_exists($k, $aRoute) && ($aRoute[$k] == $v)) { continue; }
				elseif (is_int($keyVar = array_search(':'.$k, $aTemplate))) { $aTemplate[$keyVar] = $v; continue; }
				else { continue 2; }
			}
			foreach($aTemplate as $key => $value) {	if ($value[0] == ':') { unset($aTemplate[$key]); } }
			echo '<br />',implode('/', $aTemplate),'<br />';
			return;
			break;
		}
		//if routes dont match
		$str = $params['controller'].'/'.$params['action'].((isset($params['id'])) ? $params['id'] : '');
		unset($params['controller']);
		unset($params['action']);
		unset($params['id']);
		//if it was just cai it would have matched routes
		$otherParams = array();
		foreach($params as $key => $val) { $otherParams[] = $key .'='. $val;	}
		$str .= '?'.implode('&', $otherParams);
		echo $str;
	}
*/

	static function link_to($params = array()) {
		foreach(Route::get_routes() as $sTemplate => $aRoute) {
			//if controller and action is set in params it has to match in stemplate or aroute, if matches
			//aroute the values must be same
			$aTemplate = explode('/', $sTemplate);
			foreach(array('controller', 'action') as $ca) {
				if (isset($params[$ca])) {
					if (!(isset($aRoute[$ca]) || (is_int($keyVar = array_search(':'.$ca, $aTemplate))))) { continue 2; }
					if (isset($aRoute[$ca]) && ($aRoute[$ca] != $params[$ca])) { continue 2; }
					if (!isset($keyVar)) { $keyVar = array_search(':'.$ca, $aTemplate); }
					$aTemplate[$keyVar] = $params[$ca];
					unset($params[$ca]);
				}
			}
			//i guess i can assume it matched
			$unmatchedTemplateItems = array();
			foreach($params as $k => $v) {
				if (is_int($keyVar = array_search(':'.$k, $aTemplate))) { $aTemplate[$keyVar] = $v; }
				else { $unmatchedTemplateItems[] = $k .'='. $v; }
			}
			foreach($aTemplate as $key => $value) {	if ($value[0] == ':') { unset($aTemplate[$key]); } }
			echo '<br />'. implode('/', $aTemplate) . ((count($unmatchedTemplateItems) > 0) ? '?'.implode('&', $unmatchedTemplateItems) : ''). '<br />';
			break;
		}
	}
}

Dispatch::dispatcher();
//
//Dispatch::link_to(array('controller' => 'staffss', 'action' => 'sslogin', 'id'=>'bear', 'cat' => 'dog', 'b' => 'c'));
//Dispatch::link_to(array('action' => 'productCompare', 'list' => 'apple', 'cat' => 'dog'));
//Dispatch::link_to(array('action' => 'login'));
//Dispatch::link_to(array('controller' => 'staff', 'action' => 'login'));
//Dispatch::link_to(array('action' => 'productList', 'type' => 'apple'));
//Dispatch::link_to(array('action' => 'productList'));
//Dispatch::link_to(array('action' => 'productCompare', 'list' => 'apple'));


//print_r($map);
//echo 'boiii, ur routes dont match anything! from Dispatch';


?>
<?php
/*
error_reporting(E_ALL | E_STRICT);

define('DS', DIRECTORY_SEPARATOR);
define('ROOT', (dirname(dirname(__FILE__))) . DS);

$mahees_framework_path = ROOT.'components'.DS.'emerald_framework'.DS;
require($mahees_framework_path.DS.'framework_initializer.php');


class Dispatch {

	private static $cai = array('controller' => false, 'action' => 'index', 'id' => NULL), $aGetRUrl = false;

	function Dispatch($sUrl) {
		self::$aGetRUrl = self::aClean_url($sUrl);
		unset($_GET['r']);
	}

	function connect($sTemplate, $aRoute = array()) {
		if (count(self::$aGetRUrl) > 0) {
			$aTemplate = self::aClean_url($sTemplate);
			if (!count($aTemplate)) { return false; }
			foreach($aTemplate as $key => $rule) {
				if ($rule[0] == ':') { //wildcard
					$ruleName = substr($rule, 1);
					if (isset(self::$aGetRUrl[$key])) {	self::$cai[$ruleName] = self::$aGetRUrl[$key]; unset($aRoute[$ruleName]); }
					elseif (!isset(self::$cai[$ruleName])) { self::$cai[$ruleName] = null; }
				}
				elseif ($rule != self::$aGetRUrl[$key]) { return false; }
			}
		}
		//must have matched template
		foreach($aRoute as $key => $val) { self::$cai[$key] = $aRoute[$key]; }
		foreach(self::$cai as $key => $val) { $_GET[$key] = $val; }
		print_r($_GET);
		self::execute_controller_action();

		die();
	}

	static function execute_controller_action() {
		$controller = $_GET['controller'];
		$action = $_GET['action'];
		$controllerClassName = ucfirst($controller).'_controller';
		$controller_file = APPLICATION_PATH.'controllers'.DS.$controllerClassName.'.php';
		if (file_exists($controller_file)) {
			require($controller_file);
			if ($controller_instance = new $controllerClassName()) {
				if (method_exists($controller_instance, $action)) {
					if (!$controller_instance->$action()) { //basically of the function doesnt return anything i render somthing
						return $controller_instance->render( $controller , $action );
					}
				}
				echo 'action DOESNT exist in specified class';
				return false;
			}
			echo 'no class found! or couldnt create instance of it!';
			return false;
		}
		echo 'controller file not found';
		return false;
	}


	private static function aClean_url($sUrl) {
		if ($sUrl === '') { return array(); }
		$aUrl = explode('/', $sUrl);
		if (end($aUrl) == '') {	array_pop($aUrl); }
		return $aUrl;
	}

}


$map = new Dispatch($_GET['r']);
require(CONFIG . 'routes.php');

print_r($map);
echo 'boiii, ur routes dont match anything! from Dispatch';

*/
?>